package com.johnny.gameLogic;

import java.util.ArrayList;
import java.util.Random;

import net.sf.json.JSONObject;

import com.johnny.connector.Connector;
import com.johnny.data.DataPool;
import com.johnny.data.Game28MathInfo;
import com.johnny.data.Game28MathResult;
import com.johnny.data.PlayerInfo;
import com.johnny.data.RoomInfo;
import com.johnny.data.TableInfo;
import com.johnny.data.TableState;
import com.johnny.startup.Casino28App;
import com.johnny.util.Casino28GameMath;

public class GameLogic extends Thread {
	private int sleepTime;
	private int oneSecondTimer;
	private long lastTimeMillis = System.currentTimeMillis();
	private Random random = new Random(System.currentTimeMillis());

	public GameLogic(int sleepTime) {
		this.sleepTime = sleepTime;
	}

	@Override
	public void run() {
		while (true) {
			oneSecondTimer += (System.currentTimeMillis() - lastTimeMillis);
			lastTimeMillis = System.currentTimeMillis();
			for (RoomInfo roomInfo : DataPool.getInstance().getRoomInfos()) {
				for (TableInfo tableInfo : roomInfo.getTables()) {
					switch (tableInfo.getTableState().ordinal()) {
					case 0:
						PlayerInfo bankerInfo = null;
						PlayerInfo player1Info = null;
						PlayerInfo player2Info = null;
						PlayerInfo player3Info = null;
						PlayerInfo player4Info = null;
						PlayerInfo player5Info = null;
						PlayerInfo player6Info = null;
						for (PlayerInfo playerInfo : DataPool.getInstance().getPlayerInfos()) {
							if (playerInfo.getName().equals(tableInfo.getBanker()))
								bankerInfo = playerInfo;
							else if (playerInfo.getName().equals(tableInfo.getPlayer1()))
								player1Info = playerInfo;
							else if (playerInfo.getName().equals(tableInfo.getPlayer2()))
								player2Info = playerInfo;
							else if (playerInfo.getName().equals(tableInfo.getPlayer3()))
								player3Info = playerInfo;
							else if (playerInfo.getName().equals(tableInfo.getPlayer4()))
								player4Info = playerInfo;
							else if (playerInfo.getName().equals(tableInfo.getPlayer5()))
								player5Info = playerInfo;
							else if (playerInfo.getName().equals(tableInfo.getPlayer6()))
								player6Info = playerInfo;
						}
						if (bankerInfo != null && !Casino28App.connector.isPlayerOnline(bankerInfo)) {
							if (!tableInfo.getBankerCandidateList().isEmpty()) {
								tableInfo.setBanker(tableInfo.getBankerCandidateList().get(0));
								tableInfo.getBankerCandidateList().remove(0);
							} else {
								tableInfo.setBanker("");
							}
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (player1Info != null && !Casino28App.connector.isPlayerOnline(player1Info)) {
							tableInfo.setPlayer1("");
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (player2Info != null && !Casino28App.connector.isPlayerOnline(player2Info)) {
							tableInfo.setPlayer2("");
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (player3Info != null && !Casino28App.connector.isPlayerOnline(player3Info)) {
							tableInfo.setPlayer3("");
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (player4Info != null && !Casino28App.connector.isPlayerOnline(player4Info)) {
							tableInfo.setPlayer4("");
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (player5Info != null && !Casino28App.connector.isPlayerOnline(player5Info)) {
							tableInfo.setPlayer5("");
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (player6Info != null && !Casino28App.connector.isPlayerOnline(player6Info)) {
							tableInfo.setPlayer6("");
							JSONObject object = new JSONObject();
							object.put("action", "BcStandup");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						if (tableInfo.getBankerCandidateList().size() > 0 && tableInfo.getBanker().isEmpty()) {
							tableInfo.setBanker(tableInfo.getBankerCandidateList().get(0));
							tableInfo.getBankerCandidateList().remove(0);
							JSONObject object = new JSONObject();
							object.put("action", "BcSit");
							object.put("room", roomInfo.toJsonObject());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}

						if (tableInfo.getBanker() != null && !tableInfo.getBanker().isEmpty()) {
							int bankerCount = 0;
							for (TableInfo tableInfo2 : roomInfo.getTables()) {
								if (tableInfo2.getBanker() != null && !tableInfo2.getBanker().isEmpty())
									bankerCount++;
							}
							if (roomInfo.getPlayers().size() > bankerCount) {
								tableInfo.setTableState(TableState.betting);
								tableInfo.getDoor1Players().clear();
								tableInfo.getDoor1Wagers().clear();
								tableInfo.getDoor2Players().clear();
								tableInfo.getDoor2Wagers().clear();
								tableInfo.getDoor3Players().clear();
								tableInfo.getDoor3Wagers().clear();
								tableInfo.setTimer(30);
								JSONObject object = new JSONObject();
								object.put("action", "BcStartBetting");
								object.put("room", roomInfo);
								object.put("tableId", tableInfo.getTableId());
								object.put("tableState", tableInfo.getTableState());
								Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());

							}
						}
						break;
					case 1:
						if (oneSecondTimer >= 1000)
							tableInfo.setTimer(tableInfo.getTimer() - 1);
						if (tableInfo.getTimer() == 0) {
							Game28MathInfo mathInfo = new Game28MathInfo();
							tableInfo.setTableState(TableState.showResult);
							int[] bankerCards = new int[2];
							bankerCards[0] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							bankerCards[1] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							mathInfo.setBankerCards(bankerCards);

							int[] doorCards = new int[2];
							doorCards[0] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							doorCards[1] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							mathInfo.setDoor1Cards(doorCards);

							doorCards = new int[2];
							doorCards[0] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							doorCards[1] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							mathInfo.setDoor2Cards(doorCards);

							doorCards = new int[2];
							doorCards[0] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							doorCards[1] = tableInfo.getCards().get(tableInfo.getRemainingCardCount());
							tableInfo.setRemainingCardCount(tableInfo.getRemainingCardCount() - 1);
							mathInfo.setDoor3Cards(doorCards);

							Casino28GameMath.getInstance().calculate(mathInfo);

							tableInfo.setMathInfo(mathInfo);
							tableInfo.setTimer(60);
							
							//set players'credit	
//							long leftForBanker = 0;
//							PlayerInfo banker = null;
//							for(PlayerInfo player:DataPool.getInstance().getPlayerInfos()){
//								if(player.getId().equals(tableInfo.getBanker())){
//									banker = player;
//								}							
//								for(int count = 0;count < tableInfo.getDoor1Players().size();count++){		
//									if(player.getId().equals(tableInfo.getDoor1Players().get(count))){
//										if(mathInfo.getDoor1Result().equals(Game28MathResult.win)){										
//											player.setCredits(player.getCredits()+tableInfo.getDoor1Wagers().get(count));
//											leftForBanker = leftForBanker - tableInfo.getDoor1Wagers().get(count);									
//										}
//										if(mathInfo.getDoor1Result().equals(Game28MathResult.loss)){		
//											player.setCredits(player.getCredits()-tableInfo.getDoor1Wagers().get(count));
//											leftForBanker = leftForBanker + tableInfo.getDoor1Wagers().get(count);											
//										}	
//									}
//								}
//								for(int count = 0;count < tableInfo.getDoor2Players().size();count++){
//									if(player.getId().equals(tableInfo.getDoor2Players().get(count))){
//										if(mathInfo.getDoor2Result().equals(Game28MathResult.win)){										
//											player.setCredits(player.getCredits()+tableInfo.getDoor2Wagers().get(count));
//											leftForBanker = leftForBanker - tableInfo.getDoor2Wagers().get(count);										
//										}
//										if(mathInfo.getDoor2Result().equals(Game28MathResult.loss)){										
//											player.setCredits(player.getCredits()-tableInfo.getDoor2Wagers().get(count));
//											leftForBanker = leftForBanker + tableInfo.getDoor2Wagers().get(count);										
//										}
//									}
//
//								}	
//								for(int count = 0;count < tableInfo.getDoor3Players().size();count++){
//									if(player.getId().equals(tableInfo.getDoor3Players().get(count))){
//										if(mathInfo.getDoor3Result().equals(Game28MathResult.win)){										
//											player.setCredits(player.getCredits()+tableInfo.getDoor3Wagers().get(count));
//											leftForBanker = leftForBanker - tableInfo.getDoor3Wagers().get(count);										
//										}
//										if(mathInfo.getDoor3Result().equals(Game28MathResult.loss)){										
//											player.setCredits(player.getCredits()-tableInfo.getDoor3Wagers().get(count));
//											leftForBanker = leftForBanker + tableInfo.getDoor3Wagers().get(count);										
//										}
//									}
//								}																										
//							}
//							banker.setCredits(banker.getCredits() + leftForBanker);
												
							
							JSONObject object = new JSONObject();
							object.put("action", "BcStartShowResult");
							object.put("room", roomInfo);
							object.put("tableId", tableInfo.getTableId());
							Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
						}
						break;
					case 2:
						if (oneSecondTimer >= 1000)
							tableInfo.setTimer(tableInfo.getTimer() - 1);
						if (tableInfo.getTimer() == 0) {
							if (tableInfo.getRemainingCardCount() == -1) {
								tableInfo.setCards(Casino28GameMath.getInstance().shuffle());
								tableInfo.setRemainingCardCount(tableInfo.getCards().size() - 1);
								int[] diceNumbers = new int[2];
								diceNumbers[0] = random.nextInt(6) + 1;
								diceNumbers[1] = random.nextInt(6) + 1;
								tableInfo.setDiceNumbers(diceNumbers);
								JSONObject object = new JSONObject();
								object.put("action", "BcShuffle");
								object.put("room", roomInfo);
								object.put("tableId", tableInfo.getTableId());
								Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
							}
							
							tableInfo.setMathInfo(new Game28MathInfo());
							tableInfo.setDoor1Players(new ArrayList<String>());
							tableInfo.setDoor1Wagers(new ArrayList<Long>());
							tableInfo.setDoor2Players(new ArrayList<String>());
							tableInfo.setDoor2Wagers(new ArrayList<Long>());
							tableInfo.setDoor3Players(new ArrayList<String>());
							tableInfo.setDoor3Wagers(new ArrayList<Long>());

							if (tableInfo.isCloseTable()) {
								tableInfo.setTableState(TableState.close);
								JSONObject object = new JSONObject();
								object.put("action", "BcClose");
								object.put("room", roomInfo);
								object.put("tableId", tableInfo.getTableId());
								Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
							} else {
								tableInfo.setTableState(TableState.waiting_banker);
								JSONObject object = new JSONObject();
								object.put("action", "BcWaiting_banker");
								object.put("room", roomInfo);
								object.put("tableId", tableInfo.getTableId());
								Casino28App.connector.broadcast(object.toString(), roomInfo.getRoomId());
							}
						}
						break;
					case 3:
						break;
					default:
						break;
					}
					try {
						sleep(sleepTime);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				}

			}
			if (oneSecondTimer >= 1000)
				oneSecondTimer = 0;
		}
	}
}
